package com.xuexi.mashibing;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

/**
 * 引用类型
 * 强、弱、软、虚
 *
 * 强引用：对象不会被垃圾回收器回收，除非没有其他引用指向它。适用于需要长期保存对象的场景。
 * 软引用：对象在内存不足时会被垃圾回收器回收。适用于对象不需要长期保存，但在某些情况下可能需要恢复的场景。
 * 弱引用：对象在没有其他强引用指向它时会被垃圾回收器回收。适用于不需要长期保存对象，并且可以接受对象可能被回收的场景。
 * 虚引用：对象不会对对象的生存时间有任何影响，也不能通过虚引用获取对象的内容。主要用于跟踪对象的被引用情况，通常与垃圾回收器的回收过程相关。
 */
public class ReferenceTypesExample {

    public static void main(String[] args) {
        // 创建一个对象，它将被不同类型的引用所引用
        Object obj = new Object();

        // 强引用
        strongReference(obj);

        // 软引用
        softReference(obj);

        // 弱引用
        weakReference(obj);

        // 虚引用
        phantomReference(obj);

        // 输出对象的地址，检查对象是否仍然存在
        System.out.println("Object address: " + obj);
    }

    // 强引用的使用案例
    public static void strongReference(Object obj) {
        /*// 创建一个强引用
        StrongReference strongReference = new StrongReference<>(obj);

        // 输出对象的地址，此时对象仍然存在
        System.out.println("Strong reference address: " + strongReference.get());

        // 断开强引用
        strongReference.clear();

        // 手动触发垃圾回收
        System.gc();

        // 再次输出对象的地址，此时对象已经被垃圾回收器回收，地址为空
        System.out.println("Strong reference address after garbage collection: " + strongReference.get());*/
    }

    // 软引用的使用案例
    public static void softReference(Object obj) {
        // 创建一个软引用
        SoftReference<Object> softReference = new SoftReference<>(obj);

        // 输出对象的地址，此时对象仍然存在
        System.out.println("Soft reference address: " + softReference.get());

        // 断开软引用
        softReference.clear();

        // 手动触发垃圾回收
        System.gc();

        // 再次输出对象的地址，此时对象仍然存在，因为软引用在垃圾回收时会被清理，但在内存不足时才会真正被回收
        System.out.println("Soft reference address after garbage collection: " + softReference.get());
    }

    // 弱引用的使用案例
    public static void weakReference(Object obj) {
        // 创建一个弱引用
        WeakReference<Object> weakReference = new WeakReference<>(obj);

        // 输出对象的地址，此时对象仍然存在
        System.out.println("Weak reference address: " + weakReference.get());

        // 断开弱引用
        weakReference.clear();

        // 手动触发垃圾回收
        System.gc();

        // 再次输出对象的地址，此时对象已经被垃圾回收器回收，地址为空
        System.out.println("Weak reference address after garbage collection: " + weakReference.get());
    }

    // 虚引用的使用案例
    public static void phantomReference(Object obj) {
        ReferenceQueue q = new ReferenceQueue();
        // 创建一个虚引用
        PhantomReference<Object> phantomReference = new PhantomReference<>(obj, q);

        // 输出对象的地址，此时对象仍然存在
        System.out.println("Phantom reference address: " + phantomReference.get());

        // 断开虚引用
        phantomReference.clear();

        // 手动触发垃圾回收
        System.gc();

        // 再次输出对象的地址，此时对象已经被垃圾回收器回收，地址为空
        System.out.println("Phantom reference address after garbage collection: " + phantomReference.get());
    }
}
